{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TLS 1.3 handshake overview\n",
    "This is the basic TLS 1.3 handshake:\n",
    "\n",
    "<img src=\"images/handshake_tls13.png\" alt=\"Handshake TLS 1.3\" width=\"400\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dissecting the handshake"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scapy.all import *\n",
    "load_layer('tls')\n",
    "conf.logLevel = logging.INFO"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ClientHello\n",
    "record1_str = open('raw_data/tls_session_13/01_cli.raw', 'rb').read()\n",
    "record1 = TLS(record1_str)\n",
    "sess = record1.tls_session\n",
    "record1.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The PFS relies on the ECDH secret below being kept from observers, and deleted right after the key exchange\n",
    "from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey\n",
    "\n",
    "# Used in records 2-6 + 8\n",
    "x25519_client_privkey = open('raw_data/tls_session_13/cli_key.raw', 'rb').read()\n",
    "sess.tls13_client_privshares[\"x25519\"] = X25519PrivateKey.from_private_bytes(x25519_client_privkey)\n",
    "\n",
    "# Used in records 7 + 9\n",
    "x25519_server_privkey = open('raw_data/tls_session_13/srv_key.raw', 'rb').read()\n",
    "sess.tls13_server_privshare[\"x25519\"] = X25519PrivateKey.from_private_bytes(x25519_server_privkey)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# ServerHello + ChangeCipherSpec (middlebox compatibility)\n",
    "record2_str = open('raw_data/tls_session_13/02_srv.raw', 'rb').read()\n",
    "record2 = TLS(record2_str, tls_session=sess.mirror())\n",
    "record2.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Encrypted Extensions\n",
    "record3_str = open('raw_data/tls_session_13/03_srv.raw', 'rb').read()\n",
    "record3 = TLS(record3_str, tls_session=sess)\n",
    "record3.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Certificate\n",
    "record4_str = open('raw_data/tls_session_13/04_srv.raw', 'rb').read()\n",
    "record4 = TLS(record4_str, tls_session=sess)\n",
    "record4.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Certificate verify\n",
    "record5_str = open('raw_data/tls_session_13/05_srv.raw', 'rb').read()\n",
    "record5 = TLS(record5_str, tls_session=sess)\n",
    "record5.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Finished\n",
    "record6_str = open('raw_data/tls_session_13/06_srv.raw', 'rb').read()\n",
    "record6 = TLS(record6_str, tls_session=sess)\n",
    "record6.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Client ChangeCipherSpec (middlebox compatibility) + Finished\n",
    "record7_str = open('raw_data/tls_session_13/07_cli.raw', 'rb').read()\n",
    "record7 = TLS(record7_str, tls_session=sess.mirror())\n",
    "record7.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dissecting some data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Client application data\n",
    "record8_str = open('raw_data/tls_session_13/08_cli.raw', 'rb').read()\n",
    "record8 = TLS(record8_str, tls_session=sess)\n",
    "record8.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Server application data\n",
    "record9_str = open('raw_data/tls_session_13/09_srv.raw', 'rb').read()\n",
    "record9 = TLS(record9_str, tls_session=sess.mirror())\n",
    "record9.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Observations sur TLS 1.3\n",
    "* Certificat désormais chiffré...\n",
    "* ...mais pas le Server Name dans le ClientHello\n",
    "* Risques du mode 0-RTT"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
